package com.security.gateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author yanggld
 * @Date 2020/3/9-21:24
 */
@Slf4j
@Component
public class AuthFilter extends ZuulFilter {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        log.info("******************oauth start****************");
        RequestContext cxt = RequestContext.getCurrentContext();
        HttpServletRequest request = cxt.getRequest();
        String requestURI = request.getRequestURI();
        if (StringUtils.startsWith(requestURI, "/auth")) {
            return null;
        }
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isBlank(authorization)) {
            return null;
        }
        if (!StringUtils.startsWithIgnoreCase(authorization, "bearer ")) {
            return null;
        }
        try {
            TokenInfo tokenInfo = getTokenInfo(authorization);
            request.setAttribute("tokenInfo",tokenInfo);
        } catch (Exception ex) {
            log.error("get token info error!");
        }
        return null;
    }

    private TokenInfo getTokenInfo(String authorization) {
        String token = StringUtils.substringAfter(authorization, "bearer ");
        String checkTokenEndpointUrl = "http://localhost:6001/oauth/check_token";
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.setBasicAuth("admin", "123456");
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("token", token);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, httpHeaders);

        ResponseEntity<TokenInfo> responseEntity =
            restTemplate.exchange(checkTokenEndpointUrl, HttpMethod.POST, httpEntity, TokenInfo.class);

        log.info("token info : {}",responseEntity.getBody());
        return responseEntity.getBody();
    }
}
